package graphics;

import javax.media.opengl.GL;


public class Light extends GraphicalObject  {

	static boolean lights[] = {false , false, false, false, false, false, false, false};
	int lightId = -1;
	int lightIndex = -1;

	float lightColorDiffuse[] = 	{ 1.0f, 1.0f, 1.0f, 1.0f };
	float lightColorAmbient[] = 	{ 0.5f, 0.5f, 0.5f, 1.0f };
	float lightColorSpecular[] = 	{ 1.0f, 1.0f, 1.0f, 1.0f };
	float lightPosition[] = 		{ 0.0f, 0.0f, 0.0f, 1.0f };

	private boolean hasAttenuation = false;
	private float lightAttenuation = 1f;

	
	public void setLightColorDiffuse(float[] lightColorDiffuse) {
		this.lightColorDiffuse = lightColorDiffuse;
	}
	public void setLightColorAmbient(float[] lightColorAmbient) {
		this.lightColorAmbient = lightColorAmbient;
	}
	public void setLightColorSpecular(float[] lightColorSpecular) {
		this.lightColorSpecular = lightColorSpecular;
	}
	public void setLightPosition(float[] lightPosition) {
		this.lightPosition = lightPosition;
	}

	public boolean isHasAttenuation() {
		return hasAttenuation;
	}
	public void setHasAttenuation(boolean hasAttenuation) {
		this.hasAttenuation = hasAttenuation;
	}
	public float getLightAttenuation() {
		return lightAttenuation;
	}
	public void setLightAttenuation(float lightAttenuation) {
		this.lightAttenuation = lightAttenuation;
	}
	private void allocateLight(){
		lightIndex = -1;
		lightId = -1;
		
		for (int i=0; i < lights.length; i++){
			if (lights[i] == false){
				lightIndex = i;
				break;
			}
		}

		if (lightIndex < 0)
			throw new RuntimeException("No lights available");

		lights[lightIndex] = true;
		switch(lightIndex){
		case 0 : lightId = GL.GL_LIGHT0; break;
		case 1 : lightId = GL.GL_LIGHT1; break;
		case 2 : lightId = GL.GL_LIGHT2; break;
		case 3 : lightId = GL.GL_LIGHT3; break;
		case 4 : lightId = GL.GL_LIGHT4; break;
		case 5 : lightId = GL.GL_LIGHT5; break;
		case 6 : lightId = GL.GL_LIGHT6; break;
		case 7 : lightId = GL.GL_LIGHT7; break;
		}
	}
	private void freeLight(){
		lights[lightIndex] = false;
		lightIndex = -1;
		lightId = -1;
	}
	public void enableLight(GL gl){
		gl.glEnable(lightId);
	}
	public void disableLight(GL gl){
		gl.glDisable(lightId);
	}

	@Override
	public void prerender(GL gl) {
		allocateLight();
		enableLight(gl);
		
		if (hasAttenuation){
			//gl.glLightf(lightId, GL.GL_CONSTANT_ATTENUATION, lightAttenuation);
			gl.glLightf(lightId, GL.GL_QUADRATIC_ATTENUATION, lightAttenuation);
			
		}
		gl.glLightfv(lightId, GL.GL_AMBIENT, lightColorAmbient,1);
		gl.glLightfv(lightId, GL.GL_DIFFUSE, lightColorDiffuse,1);
		gl.glLightfv(lightId, GL.GL_SPECULAR, lightColorSpecular,1);
		gl.glLightfv(lightId, GL.GL_POSITION, lightPosition,0);
		super.prerender(gl);
	}
	
	@Override
	public void render(GL gl) {
		super.render(gl);
	}
	@Override
	public void postrender(GL gl) {
		disableLight(gl);
		freeLight();
		super.postrender(gl);
	}
	@Override
	public void setParameter(String name, String[] params) {
		
		if (name.equals("attenuation")){
			hasAttenuation = true;
			lightAttenuation = Float.parseFloat(params[0]);
			return;
		}
		
		if (name.equals("ambient")){
			lightColorAmbient[1] = Float.parseFloat(params[0]);
			lightColorAmbient[2] = Float.parseFloat(params[1]);
			lightColorAmbient[3] = Float.parseFloat(params[2]);
			return;
		}

		if (name.equals("diffuse")){
			lightColorDiffuse[1] = Float.parseFloat(params[0]);
			lightColorDiffuse[2] = Float.parseFloat(params[1]);
			lightColorDiffuse[3] = Float.parseFloat(params[2]);
			return;
		}
		if (name.equals("specular")){
			lightColorSpecular[1] = Float.parseFloat(params[0]);
			lightColorSpecular[2] = Float.parseFloat(params[1]);
			lightColorSpecular[3] = Float.parseFloat(params[2]);
			return;
		}
		super.setParameter(name, params);
	}
}
